package pc

import (
	. "chess_platform/internal/common"
	"chess_platform/models/client"
	"chess_platform/models/h5"
	"chess_platform/models/pc"
	"chess_platform/modules"
	"fmt"
	"time"
)

//[pc]finance:财务管理
type FinanceController struct {
	GrantController
}

func (b *FinanceController) URLMapping() {
	//card:售卖钻石设置
	b.Mapping("ListCardPrice", b.ListCardPrice)
	b.Mapping("NewCardPrice", b.NewCardPrice)
	b.Mapping("CardPriceInfo", b.CardPriceInfo)
	b.Mapping("UpdateCardPrice", b.UpdateCardPrice)
	b.Mapping("DeleteCardPrice", b.DeleteCardPrice)
	b.Mapping("CardPrice", b.CardPrice)

	//store:商城
	b.Mapping("ListStorePrice", b.ListStorePrice)
	b.Mapping("NewStorePrice", b.NewStorePrice)
	b.Mapping("StorePriceInfo", b.StorePriceInfo)
	b.Mapping("UpdateStorePrice", b.UpdateStorePrice)
	b.Mapping("DeleteStorePrice", b.DeleteStorePrice)

	//coin:钻石兑换金币
	b.Mapping("ListCoin", b.ListCoin)
	b.Mapping("NewCoin", b.NewCoin)
	b.Mapping("CoinInfo", b.CoinInfo)
	b.Mapping("UpdateCoin", b.UpdateCoin)
	b.Mapping("DeleteCoin", b.DeleteCoin)

	//agent:代理订单
	b.Mapping("ListAgentOrder", b.ListAgentOrder)
	b.Mapping("DeliveryAgentCard", b.DeliveryAgentCard)

	//player:玩家订单(店铺订单)
	b.Mapping("ListPlayerOrder", b.ListPlayerOrder)
	b.Mapping("DeliveryPlayerCard", b.DeliveryPlayerCard)

	//app:商城商品订单
	b.Mapping("ListAppOrder", b.ListAppOrder)
	b.Mapping("DeliveryPlayerDiamond", b.DeliveryPlayerDiamond)

	//params:参数设置
	b.Mapping("ListRule", b.ListRule)
	b.Mapping("UpdateRule", b.UpdateRule)

	b.Mapping("UpdateTopUp", b.UpdateTopUp)
	b.Mapping("ListTopUp", b.ListTopUp)

	b.Mapping("ListPayType", b.ListPayType)
	b.Mapping("UpdatePayType", b.UpdatePayType)

	b.Mapping("ListH5SystemUser", b.ListH5SystemUser)
	b.Mapping("UpdateH5SystemUser", b.UpdateH5SystemUser)
	b.Mapping("GenH5SystemUserAuthCode", b.GenH5SystemUserAuthCode)

	//withdraw:提现列表
	b.Mapping("ListWithdraw", b.ListWithdraw)
	b.Mapping("UpdateWithdraw", b.UpdateWithdraw)
}

// @Title 钻石房价列表
// @Description 钻石房价列表
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Success 0 {object} []common.PcCard
// @router /card/list-card-price [post]
func (b *FinanceController) ListCardPrice() {
	var p ListParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	cr, count, err := pc.ListCardPrice(p)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	//获取一级，二级代理进货价，玩家直充进货价
	r1, err := h5.RuleByType(RuleLevel1CardPrice)
	if err != nil {
		LogPc.Error(b.SystemError(err.Error()))
		return
	}
	if r1.Id == 0 {
		b.Res.Code = ErrNotFound
		b.Res.Msg = "一级代理进货价未设置"
		b.Response()
		return
	}
	r2, err := h5.RuleByType(RuleLevel2CardPrice)
	if err != nil {
		LogPc.Error(b.SystemError(err.Error()))
		return
	}
	if r2.Id == 0 {
		b.Res.Code = ErrNotFound
		b.Res.Msg = "二级代理进货价未设置"
		b.Response()
		return
	}
	player, err := h5.RuleByType(RulePlayerCardPrice)
	if err != nil {
		LogPc.Error(b.SystemError(err.Error()))
		return
	}
	if player.Id == 0 {
		b.Res.Code = ErrNotFound
		b.Res.Msg = "玩家直充进货价未设置"
		b.Response()
		return
	}

	partner, err := h5.RuleByType(RulePfUnitCardPrice)
	if err != nil {
		LogPc.Error(b.SystemError(err.Error()))
		return
	}
	if partner.Id == 0 {
		b.Res.Code = ErrNotFound
		b.Res.Msg = "合伙人进货价未设置"
		b.Response()
		return
	}

	for _, v := range cr {
		switch v.Type {
		case RuleLevel1CardPrice:
			v.Amount = r1.Amount * v.Num
			v.UnitPrice = r1.Amount
		case RuleLevel2CardPrice:
			v.Amount = r2.Amount * v.Num
			v.UnitPrice = r2.Amount
		case RulePlayerCardPrice:
			v.Amount = player.Amount * v.Num
			v.UnitPrice = player.Amount
		case RulePartnerCardPrice:
			v.Amount = partner.Amount * v.Num
			v.UnitPrice = partner.Amount
		default:
		}
	}

	b.Res.Data = cr
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 新建钻石售卖数量及价格
// @Description 新建钻石售卖数量及价格
// @Param   type         body   int        true        "买钻石的用户类型,1-一级代理买钻石,2-二级代理买钻石,3-玩家买钻石,4-代理赠送钻石,5-合伙人买钻石"
// @Param   num          body   int        true        "钻石数量"
// @Param   give_num     body   int        true        "系统赠送的钻石数量"
// @Success 0 {string}  状态码
// @router /card/new-card-price [post]
func (b *FinanceController) NewCardPrice() {
	var p Card
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"type":     p.Type,
		"num":      p.Num,
		"give_num": p.GiveNum,
	}
	_, err := pc.NewCardPrice(data)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	key := fmt.Sprintf("%v%v", KeyCardList, p.Type)
	DelCache(RedisCache, key)

	msg := fmt.Sprintf("新建钻石售卖数量及价格")
	b.NewLog(LogFinance, OpNew, msg, data)
}

// @Title 根据id获取钻石售卖信息
// @Description 根据id获取钻石售卖信息
// @Param   id        body   int        true        "id"
// @Success 0 {string}  状态码
// @router /card/card-price-info [post]
func (b *FinanceController) CardPriceInfo() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	card, err := pc.CardPriceById(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	if card == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = "此房价不存在"
		b.Response()
	}

	var rule Rule
	switch card.Type {
	case RuleLevel1CardPrice:
		rule, err = h5.RuleByType(RuleLevel1CardPrice)
		if err != nil {
			LogPc.Error(b.SystemError(err.Error()))
			return
		}
		if rule.Id == 0 {
			b.Res.Code = ErrNotFound
			b.Res.Msg = "一级代理进货价未设置"
			b.Response()
			return
		}
		card.UnitPrice = rule.Amount
	case RuleLevel2CardPrice:
		rule, err = h5.RuleByType(RuleLevel2CardPrice)
		if err != nil {
			LogPc.Error(b.SystemError(err.Error()))
			return
		}
		if rule.Id == 0 {
			b.Res.Code = ErrNotFound
			b.Res.Msg = "二级代理进货价未设置"
			b.Response()
			return
		}
		card.UnitPrice = rule.Amount
	case RulePlayerCardPrice:
		rule, err = h5.RuleByType(RulePlayerCardPrice)
		if err != nil {
			LogPc.Error(b.SystemError(err.Error()))
			return
		}
		if rule.Id == 0 {
			b.Res.Code = ErrNotFound
			b.Res.Msg = "玩家直充进货价未设置"
			b.Response()
			return
		}
		card.UnitPrice = rule.Amount
	case RulePartnerCardPrice:
		rule, err = h5.RuleByType(RulePfUnitCardPrice)
		if err != nil {
			LogPc.Error(b.SystemError(err.Error()))
			return
		}
		if rule.Id == 0 {
			b.Res.Code = ErrNotFound
			b.Res.Msg = "合伙人进货价未设置"
			b.Response()
			return
		}
		card.UnitPrice = rule.Amount
	default:
	}

	b.Res.Data = card
	b.ResponseSuccess()
}

// @Title 更新钻石售卖数量及价格
// @Description 更新钻石售卖数量及价格
// @Param   id           body   int        true        "id"
// @Param   type         body   int        true        "买钻石的用户类型,1-一级代理买钻石,2-二级代理买钻石,3-玩家买钻石,4-代理赠送钻石,5-合伙人买钻石"
// @Param   num          body   int        true        "钻石数量"
// @Param   give_num     body   int        true        "系统赠送的钻石数量"
// @Success 0 {string}  状态码
// @router /card/update-card-price [post]
func (b *FinanceController) UpdateCardPrice() {
	var p Card
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"type":     p.Type,
		"num":      p.Num,
		"give_num": p.GiveNum,
	}
	_, err := pc.UpdateCardPrice(data, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	key := fmt.Sprintf("%v%v", KeyCardList, p.Type)
	DelCache(RedisCache, key)
	msg := fmt.Sprintf("更新钻石售卖数量及价格(ID%v)", p.Id)
	b.NewLog(LogFinance, OpUpdate, msg, data)
}

// @Title 删除钻石售卖数量及价格
// @Description 删除钻石售卖数量及价格
// @Param   id           body   int        true        "id"
// @Param   type         body   int        true        "(麻烦传个类型,方便删除缓存)买钻石的用户类型,1-一级代理买钻石,2-二级代理买钻石,3-玩家买钻石,4-代理赠送钻石,5-合伙人买钻石"
// @Success 0 {string}  状态码
// @router /card/delete-card-price [post]
func (b *FinanceController) DeleteCardPrice() {
	type Params struct {
		Id   int64 `json:"id" valid:"Required"`
		Type int64 `json:"type" valid:"Range(1,5)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	_, err := pc.DeleteCardPrice(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	key := fmt.Sprintf("%v%v", KeyCardList, p.Type)
	DelCache(RedisCache, key)
	msg := fmt.Sprintf("删除钻石售卖数量及价格(ID%v)", p.Id)
	b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
}

// @Title 钻石价格
// @Description 钻石价格
// @Param   type  body   int        true        "1-一级代理买钻石,2-二级代理买钻石,3-玩家买钻石,5-合伙人买钻石"
// @Success 0 {string}
// @router /card/card-price [post]
func (b *FinanceController) CardPrice() {
	type Params struct {
		Type int64 `json:"type" valid:"Range(1,5)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	if p.Type == 5 {
		p.Type = RulePfUnitCardPrice
	}
	rule, err := h5.RuleByType(p.Type)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	if rule.Id == 0 {
		b.ResponseFail("钻石价格未设置")
	}
	b.Res.Data = rule
	b.ResponseSuccess()
}

//----------------------------以下是商城商品---------------------

// @Title 商城钻石房价列表(展示价格时除以100)
// @Description 商城钻石房价列表(展示价格时除以100)
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Success 0 {object} []common.Store
// @router /store/list-store-price [post]
func (b *FinanceController) ListStorePrice() {
	var p ListParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	cr, count, err := pc.ListStorePrice(p)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = cr
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 新建商城商品售卖数量及价格
// @Description 新建商城商品售卖数量及价格
// @Param   num          body   int        true        "钻石数量"
// @Param   product_id   body   int        true        "苹果对应的商品id"
// @Param   amount       body   int        true        "价格,要x100再传到后端来"
// @Param   status       body   int        false       "0-正常的价格，1-是特惠"
// @Success 0 {string}  状态码
// @router /store/new-store-price [post]
func (b *FinanceController) NewStorePrice() {
	var p Store
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Num, "num").Message("请填写钻石数量")
	b.Valid.Required(p.ProductId, "product_id").Message("请填写苹果商品id")
	b.Valid.Required(p.Amount, "amount").Message("请填写钻石价格")
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"num":        p.Num,
		"amount":     p.Amount,
		"status":     p.Status,
		"product_id": p.ProductId,
	}
	_, err := pc.NewStorePrice(data)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	DelCache(RedisCache, KeyStoreList)

	msg := fmt.Sprintf("新建商城商品售卖数量及价格")
	b.NewLog(LogFinance, OpNew, msg, data)
}

// @Title 根据id获取商城商品售卖信息
// @Description 根据id获取商城商品售卖信息
// @Param   id        body   int        true        "id"
// @Success 0 {string}  状态码
// @router /store/store-price-info [post]
func (b *FinanceController) StorePriceInfo() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	store, err := pc.StorePriceById(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = store
	b.ResponseSuccess()
}

// @Title 更新商城商品售卖数量及价格
// @Description 更新商城商品售卖数量及价格
// @Param   id           body   int        true        "id"
// @Param   num          body   int        true        "钻石数量"
// @Param   product_id   body   int        true        "苹果对应的商品id"
// @Param   amount       body   int        true        "价格,要x100再传到后端来"
// @Param   status       body   int        false       "0-正常的价格，1-是特惠"
// @Success 0 {string}  状态码
// @router /store/update-store-price [post]
func (b *FinanceController) UpdateStorePrice() {
	var p Store
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Id, "id").Message("id不可缺少")
	b.Valid.Required(p.Num, "num").Message("请填写钻石数量")
	b.Valid.Required(p.ProductId, "product_id").Message("请填写苹果商品id")
	b.Valid.Required(p.Amount, "amount").Message("请填写钻石价格")
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"num":        p.Num,
		"amount":     p.Amount,
		"status":     p.Status,
		"product_id": p.ProductId,
	}
	_, err := pc.UpdateStorePrice(data, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	DelCache(RedisCache, KeyStoreList)
	msg := fmt.Sprintf("更新钻石商城商品数量及价格(ID%v)", p.Id)
	b.NewLog(LogFinance, OpUpdate, msg, data)
}

// @Title 删除商城商品售卖数量及价格
// @Description 删除商城商品售卖数量及价格
// @Param   id           body   int        true        "id"
// @Success 0 {string}  状态码
// @router /store/delete-store-price [post]
func (b *FinanceController) DeleteStorePrice() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	_, err := pc.DeleteStorePrice(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()

	DelCache(RedisCache, KeyStoreList)

	msg := fmt.Sprintf("删除商城商品售卖数量及价格(ID%v)", p.Id)
	b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
}

//-------------------------------金币兑换----------------------------------------

// @Title 钻石兑换金币列表
// @Description 钻石兑换金币列表
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Success 0 {object} []common.Store
// @router /coin/list-coin [post]
func (b *FinanceController) ListCoin() {
	var p ListParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	cr, count, err := pc.ListCoin(p)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = cr
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 新建钻石兑换金币
// @Description 新建钻石兑换金币
// @Param   diamond          body   int        true        "钻石数量"
// @Param   coin             body   int        true        "金币数量"
// @Param   title            body   string     true        "商品标题"
// @Param   sub_title        body   string     true        "商品副标题"
// @Success 0 {string}  状态码
// @router /coin/new-coin [post]
func (b *FinanceController) NewCoin() {
	var p DiamondCoin
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"diamond":   p.Diamond,
		"coin":      p.Coin,
		"title":     p.Title,
		"sub_title": p.SubTitle,
	}
	_, err := pc.NewCoin(data)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	DelCache(RedisCache, KeyDiamondCoinList)

	msg := fmt.Sprintf("新建钻石兑换金币")
	b.NewLog(LogFinance, OpNew, msg, data)
}

// @Title 根据id获取钻石兑换金币信息
// @Description 根据id获取钻石兑换金币信息
// @Param   id        body   int        true        "id"
// @Success 0 {string}  状态码
// @router /coin/coin-info [post]
func (b *FinanceController) CoinInfo() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	store, err := pc.CoinById(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = store
	b.ResponseSuccess()
}

// @Title 更新钻石兑换金币
// @Description 更新钻石兑换金币
// @Param   id               body   int        true        "id"
// @Param   diamond          body   int        true        "钻石数量"
// @Param   coin             body   int        true        "金币数量"
// @Param   title            body   string     true        "商品标题"
// @Param   sub_title        body   string     true        "商品副标题"
// @Success 0 {string}  状态码
// @router /coin/update-coin [post]
func (b *FinanceController) UpdateCoin() {
	var p DiamondCoin
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"diamond":   p.Diamond,
		"coin":      p.Coin,
		"title":     p.Title,
		"sub_title": p.SubTitle,
	}
	_, err := pc.UpdateCoin(data, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	DelCache(RedisCache, KeyDiamondCoinList)
	msg := fmt.Sprintf("更新钻石兑换金币(ID%v)", p.Id)
	b.NewLog(LogFinance, OpUpdate, msg, data)
}

// @Title 删除钻石兑换金币
// @Description 删除钻石兑换金币
// @Param   id           body   int        true        "id"
// @Success 0 {string}  状态码
// @router /coin/delete-coin [post]
func (b *FinanceController) DeleteCoin() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	_, err := pc.DeleteCoin(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()

	DelCache(RedisCache, KeyDiamondCoinList)
	msg := fmt.Sprintf("删除钻石兑换金币(ID%v)", p.Id)
	b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
}

//------------------------------代理的订单-----------------------------------------------------

// @Title 代理的订单列表(支付记录)
// @Description 代理的订单列表(支付记录)
// @Param   start_time         body   int     false      "下单开始时间"
// @Param   end_time           body   int     false      "下单结束时间"
// @Param   page_size          body   int     true       "每页显示数量"
// @Param   page_index         body   int     true       "第几页"
// @Param   uid          	   body   int     false      "用户id"
// @Param   transaction_id     body   string  false      "微信订单号"
// @Param   id                 body   int     false      "平台订单号"
// @Param   status             body   int     false      "订单状态,0-所有状态,1-未支付,2-已关闭,3-支付错误,4-支付成功,未发货,5-已发货'"
// @Param   group_id           body   int     false      "代理所属的大区"
// @Success 0 {object} []common.Order 订单(支付)列表
// @router /agent/list-agent-order [post]
func (b *FinanceController) ListAgentOrder() {
	type Params struct {
		ListParams
		ListDayParams
		AllOrderParams
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	cr, amount, count, err := pc.ListAgentOrder(p.ListParams, p.ListDayParams, p.AllOrderParams, b.Ui.GroupId)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = map[string]interface{}{
		"order":  cr,
		"amount": amount,
	}
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 补发货(钻石)
// @Description 补发货(钻石)
// @Param   id              body   int        true        "id"
// @Success 0 {string}  状态码
// @router /agent/delivery-card [post]
func (b *FinanceController) DeliveryAgentCard() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	order, err := h5.OrderById(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	if order == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrOrderNotFound
		b.Response()
		return
	}
	if order.Status == OrderDelivered {
		b.Res.Code = ErrOperationRepeat
		b.Res.Msg = MsgAlreadyDeliveryCard
		b.Response()
		return
	}
	if order.Status != OrderPaySuccess {
		b.Res.Code = ErrOrderNotPaySuccess
		b.Res.Msg = MsgOrderNotPaySuccess
		b.Response()
		return
	}

	if order.UserType == Agent {
		o := NewDBOrm(DBChessCenter)
		o.Begin()
		defer o.Rollback()
		err := modules.DeliveryH5AgentCard(order.Uid, order.CardNum, order.GiveNum, order.Amount, order.Id, o)
		if err != nil {
			o.Rollback()
			b.ResponseFail("发货失败,请联系开发人员")
			LogPc.Error(err.Error())
			return
		}
		err = modules.BonusAgent(order, o)
		if err != nil {
			o.Rollback()
			b.ResponseFail("发货失败,请联系开发人员")
			LogPc.Error(err.Error())
			return
		}
		o.Commit()
		msg := fmt.Sprintf("发货给代理(uid:%v)成功,平台订单号:%v", order.Uid, order.Id)
		b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
	} else if order.UserType == Player {
		//发货
		o := NewDBOrm(DBChessCenter)
		o.Begin()
		defer o.Rollback()
		err := modules.DeliveryH5PlayerCard(order.Uid, order.AgentId, order.CardNum, order.GiveNum, order.Amount, order.Id, o)
		if err != nil {
			o.Rollback()
			b.ResponseFail("发货失败,请联系开发人员")
		}
		//发放提成给代理
		err = modules.BonusPlayer(order, o)
		if err != nil {
			o.Rollback()
			b.ResponseFail("发放提成给代理失败,请联系开发人员")
			return
		}
		o.Commit()
		msg := fmt.Sprintf("发货给玩家(uid:%v)成功,平台订单号:%v", order.Uid, order.Id)
		b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
	}
	b.ResponseSuccess()
}

// @Title 玩家的订单列表(支付记录)
// @Description 玩家的订单列表(支付记录)
// @Param   start_time         body   int     false      "下单开始时间"
// @Param   end_time           body   int     false      "下单结束时间"
// @Param   page_size          body   int     true       "每页显示数量"
// @Param   page_index         body   int     true       "第几页"
// @Param   uid          	   body   int     false      "用户id"
// @Param   transaction_id     body   string  false      "微信订单号"
// @Param   id                 body   int     false      "平台订单号"
// @Param   status             body   int     false      "订单状态,0-所有状态,1-未支付,2-已关闭,3-支付错误,4-支付成功,未发货,5-已发货'"
// @Success 0 {object} []common.Order 订单(支付)列表
// @router /player/list-player-order [post]
func (b *FinanceController) ListPlayerOrder() {
	type Params struct {
		ListParams
		ListDayParams
		AllOrderParams
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	cr, amount, count, err := pc.ListPlayerOrder(p.ListParams, p.ListDayParams, p.AllOrderParams)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = map[string]interface{}{
		"order":  cr,
		"amount": amount,
	}
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 商城商品订单列表(支付记录)
// @Description 商城商品订单列表(支付记录)
// @Param   page_size          body   int     true       "每页显示数量"
// @Param   page_index         body   int     true       "第几页"
// @Param   start_time         body   int     false      "下单开始时间"
// @Param   end_time           body   int     false      "下单结束时间"
// @Param   uid          	   body   int     false      "用户id"
// @Param   transaction_id     body   string  false      "支付订单号"
// @Param   id                 body   int     false      "平台订单号"
// @Param   status             body   int     false      "订单状态,0-所有状态,1-未支付,2-已关闭,3-支付错误,4-支付成功,未发货,5-已发货'"
// @Param   pay_type           body   int     false      "支付类型,1-苹果，2-微信,3-支付宝"
// @Success 0 {object} []common.AppOrder 订单(支付)列表
// @router /app/list-app-order [post]
func (b *FinanceController) ListAppOrder() {
	type Params struct {
		ListParams
		ListDayParams
		AllOrderParams
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	cr, amount, count, err := pc.ListAppOrder(p.ListParams, p.ListDayParams, p.AllOrderParams)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = map[string]interface{}{
		"order":  cr,
		"amount": amount,
	}
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 补发货(钻石)
// @Description 补发货(钻石)
// @Param   id              body   int        true        "id"
// @Success 0 {string}  状态码
// @router /app/delivery-diamond [post]
func (b *FinanceController) DeliveryPlayerDiamond() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	order, err := client.OrderById(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	if order == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrOrderNotFound
		b.Response()
		return
	}
	if order.Status == OrderDelivered {
		b.Res.Code = ErrOperationRepeat
		b.Res.Msg = MsgAlreadyDeliveryCard
		b.Response()
		return
	}
	if order.Status != OrderPaySuccess {
		b.Res.Code = ErrOrderNotPaySuccess
		b.Res.Msg = MsgOrderNotPaySuccess
		b.Response()
		return
	}

	//发货
	o := NewDBOrm(DBChessCenter)
	o.Begin()
	defer o.Rollback()
	err = modules.DeliveryDiamond(order.Uid, order.Num, order.Id, o)
	if err != nil {
		o.Rollback()
		b.ResponseFail("发货失败,请联系开发人员")
	}
	o.Commit()
	msg := fmt.Sprintf("发货给玩家(uid:%v)成功,平台订单号:%v", order.Uid, order.Id)
	b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
	b.ResponseSuccess()
}

// @Title 补发货(钻石)
// @Description 补发货(钻石)
// @Param   id              body   int        true        "id"
// @Success 0 {string}  状态码
// @router /player/delivery-card [post]
func (b *FinanceController) DeliveryPlayerCard() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	order, err := h5.OrderById(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	if order == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrOrderNotFound
		b.Response()
		return
	}
	if order.Status == OrderDelivered {
		b.Res.Code = ErrOperationRepeat
		b.Res.Msg = MsgAlreadyDeliveryCard
		b.Response()
		return
	}
	if order.Status != OrderPaySuccess {
		b.Res.Code = ErrOrderNotPaySuccess
		b.Res.Msg = MsgOrderNotPaySuccess
		b.Response()
		return
	}

	if order.UserType == Agent {
		o := NewDBOrm(DBChessCenter)
		o.Begin()
		defer o.Rollback()
		err := modules.DeliveryH5AgentCard(order.Uid, order.CardNum, order.GiveNum, order.Amount, order.Id, o)
		if err != nil {
			o.Rollback()
			b.ResponseFail("发货失败,请联系开发人员")
			LogPc.Error(err.Error())
			return
		}
		err = modules.BonusAgent(order, o)
		if err != nil {
			o.Rollback()
			b.ResponseFail("发货失败,请联系开发人员")
			LogPc.Error(err.Error())
			return
		}
		o.Commit()
		msg := fmt.Sprintf("发货给代理(uid:%v)成功,平台订单号:%v", order.Uid, order.Id)
		b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
	} else if order.UserType == Player {
		//发货
		o := NewDBOrm(DBChessCenter)
		o.Begin()
		defer o.Rollback()
		err := modules.DeliveryH5PlayerCard(order.Uid, order.AgentId, order.CardNum, order.GiveNum, order.Amount, order.Id, o)
		if err != nil {
			o.Rollback()
			b.ResponseFail("发货失败,请联系开发人员")
		}
		//发放提成给代理
		err = modules.BonusPlayer(order, o)
		if err != nil {
			o.Rollback()
			b.ResponseFail("发放提成给代理失败,请联系开发人员")
			return
		}
		o.Commit()
		msg := fmt.Sprintf("发货给玩家(uid:%v)成功,平台订单号:%v", order.Uid, order.Id)
		b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
	}
	b.ResponseSuccess()
}

// @Title 更新各种规则(提现，进货价,手续费,税费,等等)
// @Description 更新各种规则(提现，进货价,手续费,税费,等等)
// @Param   id           body   int        true        "id"
// @Param   type         body   int        true        "类型"
// @Param   amount       body   int        true        "提成金额或手续费百分比"
// @Success 0 {string}  状态码
// @router /params/update-rule [post]
func (b *FinanceController) UpdateRule() {
	// id我想去掉，数据库里已经去掉了，前端还没有,再协调
	type Params struct {
		Id     int64 `json:"id" valid:"Required"`
		Amount int64 `json:"amount"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"amount": p.Amount,
	}
	_, err := pc.UpdateRule(data, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	//更新了就更新到缓存里,这样能实时生效
	//TODO: id应该改成type的
	Key := fmt.Sprintf("%v%v", KeyRuleType, p.Id)
	SetCache(RedisCache, Key, p, CacheExpire)
	b.ResponseSuccess()

	msg := fmt.Sprintf("更新各种规则(类型:%v,数值:%v)", p.Id, p.Amount)
	b.NewLog(LogFinance, OpUpdate, msg, data)

}

// @Title 各种规则列表(开店提成，玩家直充提成，提现手续费等)
// @Description 各种规则列表(开店提成，玩家直充提成，提现手续费等)
// @Success 0 {object} []common.CashRule
// @router /params/list-rule [post]
func (b *FinanceController) ListRule() {
	cr, err := pc.ListRule()
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = cr
	b.ResponseSuccess()
}

// @Title 更新第一次充值金额及钻石
// @Description 更新第一次充值金额及钻石
// @Param   id           body   int        true        "id"
// @Param   amount       body   int        true        "第一次购买钻石金额"
// @Param   card_num     body   int        true        "钻石数量"
// @Success 0 {string}  状态码
// @router /params/update-top-up [post]
func (b *FinanceController) UpdateTopUp() {
	type Params struct {
		Id      int64 `json:"id" valid:"Required"`
		Amount  int64 `json:"amount" valid:"Required"`
		CardNum int64 `json:"card_num" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"amount":   p.Amount,
		"card_num": p.CardNum,
	}
	_, err := pc.UpdateTopUp(data, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	msg := fmt.Sprintf("更新第一次充值规则")
	b.NewLog(LogFinance, OpUpdate, msg, data)

}

// @Title 第一次充值金额及钻石列表
// @Description 第一次充值金额及钻石列表
// @Success 0 {object} []common.TopUp
// @router /params/list-top-up [post]
func (b *FinanceController) ListTopUp() {
	tu, err := pc.ListTopUp()
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = tu
	b.ResponseSuccess()
}

// @Title 更新支付比例
// @Description 更新各种规则(提现，进货价,手续费,税费,等等)
// @Param   id           body   int        true        "id"
// @Param   percent      body   int        false       "比例,取值范围为0-100, 0-表示此支付不会被选到"
// @Param   remark       body   string     false       "备注"
// @Success 0 {string}  状态码
// @router /params/update-pay-type [post]
func (b *FinanceController) UpdatePayType() {
	type Params struct {
		Id      int64  `json:"id" valid:"Required"`
		Percent int64  `json:"percent"`
		Remark  string `json:"remark"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	data := map[string]interface{}{
		"percent": p.Percent,
		"remark":  p.Remark,
	}
	_, err := pc.UpdatePayType(data, p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	//重新初始化,实时生效
	errs := SendMsgToInitAlgorithm()
	if len(errs) > 0 {
		LogPc.Error(b.SystemError(errs...))
		return
	}
	b.ResponseSuccess()

	msg := fmt.Sprintf("更新支付比例(ID:%v)", p.Id)
	b.NewLog(LogFinance, OpUpdate, msg, data)

}

// @Title 支付比例列表
// @Description 区域游戏列表
// @Success 0 {object} []common.PayType 支付方式比例列表
// @router /params/list-pay-type [post]
func (b *FinanceController) ListPayType() {
	cr, err := pc.ListPayType()
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = cr
	b.ResponseSuccess()
}

// @Title H5系统帐号信息
// @Description H5系统帐号信息
// @Success 0 {object} pc.H5SysUser H5系统帐号信息
// @router /params/list-h5-sys-user [post]
func (b *FinanceController) ListH5SystemUser() {
	cr, err := pc.ListH5SystemUser()
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = cr
	b.ResponseSuccess()
}

// @Title 更新H5系统帐号信息
// @Description 更新H5系统帐号信息
// @Param   phone        body   string     true       "手机号"
// @Param   nickname     body   string     true       "系统帐号名称"
// @Param   head_img_url body   string     true       "系统头像"
// @Success 0 {string}  状态码
// @router /params/update-h5-sys-user [post]
func (b *FinanceController) UpdateH5SystemUser() {
	type Params struct {
		Phone      string `json:"phone"`
		Nickname   string `json:"nickname"`
		HeadImgUrl string `json:"head_img_url"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Phone, "phone").Message("请输入手机号")
	b.Valid.Required(p.Nickname, "nickname").Message("请输入帐号名称")
	data := map[string]interface{}{
		"phone":        p.Phone,
		"nickname":     p.Nickname,
		"head_img_url": p.HeadImgUrl,
	}
	_, err := h5.UpdateUser(data, 0)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	msg := fmt.Sprintf("更新H5系统帐号信息")
	b.NewLog(LogFinance, OpUpdate, msg, data)
}

// @Title 生成新H5系统帐号授权码
// @Description 生成新H5系统帐号授权码
// @Success 0 {string}  状态码
// @router /params/gen-new-auth-code [post]
func (b *FinanceController) GenH5SystemUserAuthCode() {
	//系统帐号为0,系统帐号生成的授权码是为一级代理使用的
	newAuthCode, err := modules.GenOrUpdateAuthCode(0, Level1)
	if err != nil {
		LogPc.Error(b.SystemError(err.Error()))
		return
	}
	b.Res.Data = newAuthCode
	b.ResponseSuccess()
	msg := fmt.Sprintf("更新H5系统帐号授权码为:%v", newAuthCode)
	b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
}

//-------------------------------提现相关-------------------------------------------

// @Title 提现列表
// @Description 提现列表
// @Param   start_time   body   int     true       "开始时间"
// @Param   end_time     body   int     true       "结束时间"
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   id           body   int     false      "提现单号"
// @Param   uid          body   int     false      "代理id"
// @Param   status       body   int     false      "提现状态,1-审批中,2-审批成功,3-审批失败,4-支付中,5-支付失败,6-支付成功"
// @Success 0 {object} []common.WithdrawRecord
// @router /withdraw/list-withdraw [post]
func (b *FinanceController) ListWithdraw() {
	type Params struct {
		ListParams
		ListDayParams
		Id     int64 `json:"id"`
		Uid    int64 `json:"uid"`
		Status int64 `json:"status"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	cr, count, pAmount, uAmount, err := pc.ListWithdraw(p.ListParams, p.ListDayParams, b.Ui.GroupId, p.Id, p.Uid, p.Status)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = map[string]interface{}{
		"unprocessed_amount": uAmount,
		"processed_amount":   pAmount,
		"withdraw_list":      cr,
	}
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 更新提现记录状态
// @Description 更新提现记录状态
// @Param   id           body   int     true       "id"
// @Param   status       body   int     true       "状态"
// @Param   fail_reason  body   int     false      "失败原因,最多32字符"
// @Success 0 {string}  状态码
// @router /withdraw/update-withdraw [post]
func (b *FinanceController) UpdateWithdraw() {
	type Params struct {
		Id         int64  `json:"id" valid:"Required"`
		Status     int64  `json:"status" valid:"Range(2,6)"`
		FailReason string `json:"fail_reason"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if p.FailReason != "" {
		b.Valid.MaxSize(p.FailReason, 32, "fail_reason").Message("最多32个字符")
	}
	if !b.ValidParams(&p) {
		return
	}
	wr, err := pc.WithdrawById(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	if wr == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrWithdrawNotFound
		b.Response()
		return
	}
	if wr.Status == WithdrawPaySuccess {
		b.Res.Code = ErrOperationRepeat
		b.Res.Msg = "提现已经支付成功,不能再改变其状态"
		b.Response()
		return
	}
	if wr.Status == WithdrawApproveFail || wr.Status == WithdrawPayFail {
		b.Res.Code = ErrOperationRepeat
		b.Res.Msg = "提现为失败状态,不能再改变其状态"
		b.Response()
		return
	}

	//状态改为失败时，要把钱退还给代理
	if p.Status == WithdrawPayFail || wr.Status == WithdrawApproveFail {
		o := NewDBOrm(DBChessCenter)
		o.Begin()
		defer o.Rollback()
		//提现金额退回记录
		cr := map[string]interface{}{
			"agent_id":    b.Uid,
			"type":        CashWithdrawReturn,
			"amount":      wr.Amount,
			"month":       CurrentYearMonth(),
			"create_time": time.Now().Unix(),
		}
		_, err = h5.NewCashRecord(cr, o)
		if err != nil {
			o.Rollback()
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
		//提现金额退回
		n, err := h5.UpdateCash(wr.Amount, b.Uid, false, o)
		if err != nil || n == 0 {
			o.Rollback()
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}

		data := map[string]interface{}{
			"status":      p.Status,
			"fail_reason": p.FailReason,
		}
		_, err = pc.UpdateWithdraw(data, p.Id, o)
		if err != nil {
			o.Rollback()
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
		o.Commit()
		b.ResponseSuccess()
		msg := fmt.Sprintf("更新提现单状态(状态ID:%v,提现单号:%v)", p.Status, p.Id)
		b.NewLog(LogFinance, OpUpdate, msg, data)
	} else {
		data := map[string]interface{}{
			"status":      p.Status,
			"fail_reason": p.FailReason,
		}
		if p.Status == WithdrawPaySuccess {
			data["pay_time"] = time.Now().Unix()
		}
		_, err = pc.UpdateWithdraw(data, p.Id)
		if err != nil {
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
		b.ResponseSuccess()
		msg := fmt.Sprintf("更新提现单状态(状态ID:%v,提现单号:%v)", p.Status, p.Id)
		b.NewLog(LogFinance, OpUpdate, msg, data)
	}
}
